#include <stdio.h>


// #define DEBUG_PRINT printf("file:%s\tline:%d\t \
//                             date:%s\ttime:%S\n"\
//                             __FILE__,__LINE__  \
//                             __DATE__,__TIME__)



// int main()
// {
//     int i = 0;
//     for(i = 0;i < 10;i++)
//     {
//         printf("file:%s line=%d date:%s time:%s i=%d\n",__FILE__,__LINE__,__DATE__,__TIME__,i);
//     }
// }


// #define SQUARE(x) x*x 
// // 不要吝啬括号 SQUARE(x) ((x)*(x))
// int main()
// {
//     int r = SQUARE(5+1);
//     //5+1*5+1 = 11
//     printf("%d\n",r);
//     return 0;
// }



// #define PRINT(X) printf("the value of "#X" is %d\n",X)
// //#会被替换成""置于变量前后，又因为字符串会自动拼接 所以能实现
// int main()
// {
//     // printf("hello ""world\n");//字符串会自动拼接
//     int a = 10;
//     // printf("the value of a is %d\n",a);
//     PRINT(a);
//     int b = 20;
//     // printf("the value of b is %d\n",b);
//     PRINT(b);
//     return 0;
// }



// //若要实现不同变量类型的打印输出可多定义一个变量
// #define PRINT(FORMAT,VALUE) printf("the value of "#VALUE" is "FORMAT"\n",VALUE)
// int main()
// {
//     int a = 10;
//     float b = 3.14f;
//     PRINT("%d",a);
//     PRINT("%lf",b);
//     return 0;
// }




// #define CAT(Class,Num) Class##Num
// int main()
// {
//     int Class106 = 10;
//     printf("%d\n",Class106);
//     printf("%d\n",CAT(Class,106));
//     return 0;
// }




//已换新电脑 

// #define MAX(x,y) (x) > (y) ? (x) : (y)

// int main()
// {
//     int n = MAX(2,4);
//     printf("%d\n",n);
//     int a = 5;
//     int b = 4;
//     int m = MAX(a++,b++);
//     printf("m = %d\n",m);
//     printf("a= %d b =%d",a,b);
//     return 0;
// }




// //宏定义可以实现函数无法实现的功能
// #define MALLOC(NUM,TYPE) (TYPE*)malloc ((NUM)* sizeof(TYPE))
// int main()
// {
//     int* p = MALLOC(10,int);
//     return 0;
// }



// int mian()
// {
//     int i = 0;
//     int arr[ARRAY_SIZE]= {0};
//     for(i = 0;i<ARRAY_SIZE;i++)
//     {
//         arr[i] = i;
//     }
//     for(i = 0;i<ARRAY_SIZE;i++)
//     {
//         printf("%d ",arr[i]);
//     }
//     return 0;
// }
// //可在终端中用linx编译指令来定义ARRAY_SIZE的值




//条件编译的类型

// #include <stdio.h>
// #define __DEBUG__
// int main()
// {
//     int i = 0;
//     int arr[10] = {0};
//     for (i = 0; i < 10; i++)
//     {
//         arr[i] = i;
// #ifdef __DEBUG__
//         printf("%d\n", arr[i]); // 为了观察数组是否赋值成功。
// #endif                          //__DEBUG__
//     }
//     return 0;
// }

// int main()
// {
// #if 1
//     printf("hehe\n");
// #endif
//     return 0;
// }

// //多分支的条件编译
// #define M 5
// int main()
// {
// #if M < 5
//     printf("hehe\n");
// #elif M == 5
//     printf("heihei\n");
// #else
//     printf("haha\n");
// #endif
//     return 0;
// }

// #define MAX 100
// int main()
// {
// #ifdef MAX
//     printf("max\n");
// #endif
// #ifndef MAX
//     printf("haha\n")
// #endif
//     return 0;

// #if defined(MAX)
//     printf("max\n");
// #endif
// #if !defined(MAX)
//     printf("haha\n")
// #endif
// }

// //还有嵌套指令 可以参照stdio等库文件的内容




// //防止同一个头文件被多次包含的方法
// //方法1
// #pragma once
// //代码

// //方法2
// #ifndef __TEST_H__
// #define __TEST_H__
// //代码
// #endif





//写一个函数模拟offsetof宏的功能
//先来看offsetof的使用
#include <stddef.h>
#define OFFSETOF(type,m_name) (size_t)&(((type*)0)->m_name)
//把0当做地址来解读 强制转换成type型的地址
struct S
{
    char c1;
    int i;
    char c2;
};
int main()
{
    struct S s = {0};
    printf("%d\n",offsetof(struct S,c1));
    printf("%d\n",offsetof(struct S,i));
    printf("%d\n",offsetof(struct S,c2));
    printf("%d\n",OFFSETOF(struct S,c1));
    printf("%d\n",OFFSETOF(struct S,i));
    printf("%d\n",OFFSETOF(struct S,c2));
    return 0;
}